#include "voda.h"
#include "runtime.h"
#include "context.h"
#include "globals.h"

#include <openssl/evp.h>
#include <openssl/sha.h>

#if defined(_WIN32)

//	#include "detail/win32_id.hpp"

#elif defined (ANDROID) || defined (__ANDROID__)

//	#include "detail/android_id.hpp"

#elif defined (__LINUX__)

//	#error Not yed defined

#endif

namespace voda
{
	globals::globals (runtime const & rt, context const & cx)
		: rt_ (rt)
		, cx_ (cx)
		, global_ ()
	{
		runtime::lock const rl (rt);
		context::lock const cl (cx);

		/* The class of the global object. */
		static JSClass my_global_class =
		{
			"global",
			JSCLASS_NEW_RESOLVE | JSCLASS_GLOBAL_FLAGS,
			JS_PropertyStub,
			JS_DeletePropertyStub,
			JS_PropertyStub,
			JS_StrictPropertyStub,
			JS_EnumerateStub,
			JS_ResolveStub,
			JS_ConvertStub,
			nullptr,
			JSCLASS_NO_OPTIONAL_MEMBERS
		};

		//	Whatever is this
		JS::CompartmentOptions const compartment;

		/* Create the global object in a new compartment. */
		JSObject * global = JS_NewGlobalObject (cx, &my_global_class, NULL, compartment);
		if (!global)
		{
			JS_ReportError (cx, "JS_NewGlobalObject failed!");
			return;
		}

		/* Set the context's global */
		JSAutoCompartment ac (cx, global);
		JS_SetGlobalObject (cx, global);

		/* Populate the global object with the standard globals, like Object and Array. */
		if (!JS_InitStandardClasses (cx, global))
		{
			JS_ReportError (cx, "JS_InitStandardClasses failed!");
			return;
		}

		if (!JS_InitReflect (cx, global))
		{
			JS_ReportError (cx, "JS_InitReflect failed!");
			return;
		}

#ifdef JS_HAS_CTYPES

		if (!JS_InitCTypesClass (cx, global))
		{
			JS_ReportError (cx, "JS_InitCTypesClass failed!");
			return;
		}

#endif//JS_HAS_CTYPES

#ifdef JS_GC_ZEAL

		JS_SetGCZeal(cx, 2, 50);

#endif//JS_GC_ZEAL
		
		global_ = global;
	}

	globals::~globals (void)
	{
	}
}